package com.example.flight_ticket_app.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.flight_ticket_app.Mapper.*;
import com.example.flight_ticket_app.Utils.ThreadUtil;
import com.example.flight_ticket_app.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ServerService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PlaneMapper planeMapper;

    @Autowired
    private FlightMapper flightMapper;

    @Autowired
    private TicketMapper ticketMapper;

    @Autowired
    private BelongMapper belongMapper;

    @Autowired
    private IndentMapper indentMapper;

    @Autowired
    private RefundMapper refundMapper;

    @Autowired
    private PassengerMapper passengerMapper;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private ThreadUtil threadUtil;

    public Result login(User user) throws Exception{
        User u = userMapper.selectOne(new QueryWrapper<User>().eq("username",user.getUsername()).eq("password",user.getPassword()));
        if(u != null){
            return new Result(200, u, "登录成功！");
        }else{
            return new Result(401,"用户名或密码错误！");
        }
    }

    public Result getPlanePage(Integer pageSize, Integer pageNum) throws Exception{
        Map<String, Object> maps = new HashMap<>();
        Page<Plane> page = new Page<>(pageNum, pageSize);
        page = planeMapper.selectPage(page, null);
        maps.put("planeList", page.getRecords());
        maps.put("total", planeMapper.selectCount(null));
        return new Result(200, maps);
    }

    public Result getFlightPage(Integer pageSize, Integer pageNum) throws Exception{
        Map<String, Object> maps = new HashMap<>();
        Page<Flight> page = new Page<>(pageNum, pageSize);
        Page<Flight> flightList = flightMapper.selectPage(page, null);
        maps.put("flightList", flightList.getRecords());
        maps.put("total", flightMapper.selectCount(null));
        return new Result(200, maps);
    }

    public Result getTicketPage(Integer pageSize, Integer pageNum) throws Exception{
        Map<String, Object> maps = new HashMap<>();
        Page<Ticket> page = new Page<>(pageNum, pageSize);
        Page<Ticket> ticketPage = ticketMapper.selectPage(page,null);
        List<Ticket> tickets = ticketPage.getRecords();
        Belong belong = null;
        for (Ticket ticket : tickets) {
          belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("ticket_id", ticket.getTicketId()));
          ticket.setFlightId(belong.getFlightId());
          ticket.setEconomyClass(belong.getEconomyClass());
          ticket.setBusinessClass(belong.getBusinessClass());
        }
        maps.put("ticketList", tickets);
        maps.put("total", ticketMapper.selectCount(null));
        return new Result(200, maps);
    }

    public Result getIndentPage(Integer pageSize, Integer pageNum) throws Exception{
        Map<String, Object> maps = new HashMap<>();
        Page<Indent> page = new Page<>(pageNum, pageSize);
        Page<Indent> indentPage = indentMapper.selectPage(page, new QueryWrapper<Indent>().eq("refund",0));
        List<Indent> indents = indentPage.getRecords();
        Passenger passenger = null;
        Ticket ticket = null;
        for (Indent indent : indents) {
            passenger = passengerMapper.selectById(indent.getPassengerId());
            ticket = ticketMapper.selectById(indent.getTicketId());
            indent.setName(passenger.getName());
            indent.setPrice(indent.getCabin() == 1 ? ticket.getBusinessPrice() : ticket.getEconomyPrice());
        }
        maps.put("indentList", indents);
        maps.put("total", indentMapper.selectCount(null));
        return new Result(200, maps);
    }

    public Result getRefundPage(Integer pageSize, Integer pageNum) throws Exception{
        Map<String, Object> maps = new HashMap<>();
        Page<Refund> page = new Page<>(pageNum, pageSize);
        Page<Refund> refundPage = refundMapper.selectPage(page,null);
        maps.put("refundList",refundPage.getRecords());
        maps.put("total",refundMapper.selectCount(null));
        return new Result(200, maps);
    }

    public Result deletePlane(Integer planeId) throws Exception{
        Task task = taskMapper.selectOne(new QueryWrapper<Task>().eq("plane_id",planeId));
        if(task != null) {
            Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id", task.getFlightId()));
            ticketMapper.deleteById(belong.getTicketId());
            flightMapper.deleteById(task.getFlightId());
        }
        planeMapper.deleteById(planeId);
        return new Result(200, "删除成功！");
    }

    public Result deleteFlight(String flightId) throws Exception{
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id",flightId));
        ticketMapper.deleteById(belong.getTicketId());
        flightMapper.deleteById(flightId);
        return new Result(200, "删除成功！");
    }

    public Result deleteIndent(Integer id) throws Exception{
        Indent indent = indentMapper.selectById(id);
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("ticket_id", indent.getTicketId()));
        if(indent.getCabin() == 1){
            belong.setBusinessClass(belong.getBusinessClass() + 1);
            belongMapper.updateById(belong);
        }else{
            belong.setEconomyClass(belong.getEconomyClass() + 1);
            belongMapper.updateById(belong);
        }
        indent.setRefund(1);
        refundMapper.insert(new Refund(indent.getTicketId(), new Date(), indent.getIndentId()));
        indentMapper.updateById(indent);
        return new Result(200, "删除成功！");
    }

    public Result deleteRefund(Integer id) throws Exception{
        Refund refund = refundMapper.selectById(id);
        indentMapper.deleteById(refund.getIndentId());
        return new Result(200, "删除成功！");
    }

    public Result addFlight(Flight flight, String gate, Integer planeId) throws Exception{
        Plane plane = planeMapper.selectById(planeId);
        flight.setPlaneId(planeId);
        planeMapper.update(null, new UpdateWrapper<Plane>().eq("plane_id",flight.getPlaneId()).set("status",1));
        flightMapper.insert(flight);
        taskMapper.insert(new Task(flight.getFlightId(), planeId));
        Ticket ticket = new Ticket();
        ticket.setGate(gate);
        ticket.setTakeOffDate(flight.getTakeOffDate());
        ticket.setArriveDate(flight.getArriveDate());
        ticket.setTakeOffAerodrome(flight.getTakeOffAerodrome());
        ticket.setArriveAerodrome(flight.getArriveAerodrome());
        ticket.setBusinessPrice(flight.getBusinessPrice());
        ticket.setEconomyPrice(flight.getEconomyPrice());
        ticketMapper.insert(ticket);
        belongMapper.insert(new Belong(flight.getFlightId(),ticket.getTicketId(),plane.getEconomyClass(),plane.getBusinessClass()));
        threadUtil.createFlightThread(flight);
        return new Result(200, "创建成功！");
    }

    public Result addPlane(Plane plane) throws Exception{
        planeMapper.insert(plane);
        return new Result(200, "添加成功！");
    }

    public Result getPlaneMessage(Integer planeId) throws Exception{
        return new Result(200, planeMapper.selectById(planeId));
    }

    public Result getIdlePlane() throws Exception{
        List<Plane> planes = planeMapper.selectList(new QueryWrapper<Plane>().eq("status",0));
        return new Result(200, planes);
    }

    public Result modifyPlaneMessage(Plane plane) throws Exception{
        planeMapper.updateById(plane);
        return new Result(200,"修改成功！");
    }

    public Result modifyGate(Integer ticketId, String gate) throws Exception{
        ticketMapper.update(null, new UpdateWrapper<Ticket>().eq("ticket_id",ticketId).set("gate",gate));
        return new Result(200, "修改成功！");
    }

    public Result addIndent(Passenger passenger, String flightId, Integer cabin) throws Exception{
        Passenger p = passengerMapper.selectById(passenger.getPassengerId());
        if(p == null){
            passengerMapper.insert(passenger);
            p = passenger;
        }else{
            passengerMapper.updateById(passenger);
        }
        if(indentMapper.selectOne(new QueryWrapper<Indent>().eq("passenger_id",p.getPassengerId()).eq("refund",0)) != null){
            return new Result(406,"该身份号已持有某航班机票！");
        }
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id",flightId));
        Ticket ticket = ticketMapper.selectById(belong.getTicketId());
        if(cabin == 1){
            if(belong.getBusinessClass() == 0){
                return new Result(406,"暂无余票！");
            }else{
                belong.setBusinessClass(belong.getBusinessClass() - 1);
                belongMapper.updateById(belong);
                indentMapper.insert(new Indent(ticket.getTicketId(),p.getPassengerId(),new Date(),cabin));
            }
        }else{
            if(belong.getEconomyClass() == 0){
                return new Result(406,"暂无余票！");
            }else{
                belong.setEconomyClass(belong.getEconomyClass() - 1);
                belongMapper.updateById(belong);
                indentMapper.insert(new Indent(ticket.getTicketId(),p.getPassengerId(),new Date(),cabin));
            }
        }
        return new Result(200, "购买成功！");
    }

    public Result getFlightPassengers(String flightId) throws Exception{
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id",flightId));
        List<Indent> indents = indentMapper.selectList(new QueryWrapper<Indent>().eq("ticket_id", belong.getTicketId()).eq("refund",0));
        List<Passenger> passengers = new ArrayList<>();
        for (Indent indent : indents) {
            passengers.add(passengerMapper.selectById(indent.getPassengerId()));
        }
        return new Result(200, passengers);
    }

    public Result deleteIndentByPassengerId(String passengerId) throws Exception{
        Indent indent = indentMapper.selectOne(new QueryWrapper<Indent>().eq("passenger_id",passengerId).eq("refund",0));
        indent.setRefund(1);
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("ticket_id", indent.getTicketId()));
        if(indent.getCabin() == 0){
            belong.setEconomyClass(belong.getEconomyClass() + 1);
        }else{
            belong.setBusinessClass(belong.getBusinessClass() + 1);
        }
        belongMapper.updateById(belong);
        indentMapper.updateById(indent);
        refundMapper.insert(new Refund(indent.getTicketId(), new Date(), indent.getIndentId()));
        return new Result(200, "删除成功！");
    }

    public Result getEconomyClass(Passenger passenger, String flightId) throws Exception{
        Passenger p = passengerMapper.selectById(passenger.getPassengerId());
        if(p == null){
            passengerMapper.insert(passenger);
            p = passenger;
        }else{
            passengerMapper.updateById(passenger);
        }
        if(indentMapper.selectOne(new QueryWrapper<Indent>().eq("passenger_id",p.getPassengerId()).eq("refund",0)) != null){
            return new Result(406,"该身份号已持有某航班机票！");
        }
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id",flightId));
        Ticket ticket = ticketMapper.selectById(belong.getTicketId());
        if(belong.getEconomyClass() == 0){
            return new Result(406, "暂无余票！");
        }else{
            belong.setEconomyClass(belong.getEconomyClass() - 1);
            belongMapper.updateById(belong);
            indentMapper.insert(new Indent(ticket.getTicketId(),p.getPassengerId(),new Date(),0));
        }
        return new Result(200, "购买成功！");
    }

    public Result getBusinessClass(Passenger passenger, String flightId) throws Exception{
        Passenger p = passengerMapper.selectById(passenger.getPassengerId());
        if(p == null){
            passengerMapper.insert(passenger);
            p = passenger;
        }else{
            passengerMapper.updateById(passenger);
        }
        if(indentMapper.selectOne(new QueryWrapper<Indent>().eq("passenger_id",p.getPassengerId()).eq("refund",0)) != null){
            return new Result(406,"该身份号已持有某航班机票！");
        }
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id",flightId));
        Ticket ticket = ticketMapper.selectById(belong.getTicketId());
        if(belong.getBusinessClass() == 0){
            return new Result(406, "暂无余票！");
        }else{
            belong.setBusinessClass(belong.getBusinessClass() - 1);
            belongMapper.updateById(belong);
            indentMapper.insert(new Indent(ticket.getTicketId(),p.getPassengerId(),new Date(),1));
        }
        return new Result(200, "购买成功！");
    }

    public Result getFlightMessage(Integer indentId) throws Exception{
        Indent indent = indentMapper.selectById(indentId);
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("ticket_id", indent.getTicketId()));
        Flight flight = flightMapper.selectById(belong.getFlightId());
        List<Flight> list = new ArrayList<>();
        list.add(flight);
        return new Result(200,list);
    }

    public Result getFlight(String flightId) throws Exception{
        Flight flight = flightMapper.selectById(flightId);
        flight.setPlaneId(taskMapper.selectOne(new QueryWrapper<Task>().eq("flight_id",flight.getFlightId())).getPlaneId());
        return new Result(200, flight);
    }

    public Result modifyFlight(Flight flight) throws Exception{
        flightMapper.updateById(flight);
        taskMapper.update(null, new UpdateWrapper<Task>().eq("flight_id",flight.getFlightId()).set("plane_id",flight.getPlaneId()));
        Belong belong = belongMapper.selectOne(new QueryWrapper<Belong>().eq("flight_id",flight.getFlightId()));
        Ticket ticket = ticketMapper.selectById(belong.getTicketId());
        ticket.setEconomyPrice(flight.getEconomyPrice());
        ticket.setBusinessPrice(flight.getBusinessPrice());
        ticket.setArriveAerodrome(flight.getArriveAerodrome());
        ticket.setTakeOffAerodrome(flight.getTakeOffAerodrome());
        ticket.setArriveDate(flight.getArriveDate());
        ticket.setTakeOffDate(flight.getTakeOffDate());
        ticketMapper.updateById(ticket);
        return new Result(200, "修改成功！");
    }

    public Result getIndentMessage(Integer indentId) throws Exception{
        Indent indent = indentMapper.selectById(indentId);
        Passenger passenger = passengerMapper.selectById(indent.getPassengerId());
        Ticket ticket = ticketMapper.selectById(indent.getTicketId());
        indent.setName(passenger.getName());
        indent.setPrice(indent.getCabin() == 1 ? ticket.getBusinessPrice() : ticket.getEconomyPrice());
        List<Indent> list = new ArrayList<>();
        list.add(indent);
        return new Result(200, list);
    }
}
